package com.woniu.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.woniu.commons.exception.VenueRuntimeException;
import com.woniu.commons.exception.YogaException;
import com.woniu.commons.model.RedisKey;
import com.woniu.commons.model.StateData;
import com.woniu.dao.YVenueBaseMapper;
import com.woniu.dao.YVenueClassroomMapper;
import com.woniu.model.form.AddClassroomForm;
import com.woniu.model.model.YQualification;
import com.woniu.model.model.YVenueBase;
import com.woniu.model.model.YVenueClassroom;
import com.woniu.model.param.PageAllClassroomParam;
import com.woniu.model.param.PageParam;
import com.woniu.service.YVenueClassroomService;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author EdisonLiu
 * @since 2024年05月23日
 */
@Service
public class YVenueClassroomServiceImpl extends ServiceImpl<YVenueClassroomMapper, YVenueClassroom> implements YVenueClassroomService {

    @Resource
    private RedissonClient redissonClient;
    @Resource
    private YVenueClassroomMapper venueClassroomMapper;
    @Resource
    private YVenueBaseMapper venueBaseMapper;

    /**
     * 根据id查询教室
     * @param id
     * @return YVenueClassroom
     */
    @Override
    public YVenueClassroom loadClassroomById(Integer id) throws YogaException{

        YVenueClassroom venueClassroom = venueClassroomMapper.selectOne(new QueryWrapper<YVenueClassroom>().eq("id", id).eq("classroom_state", 1));
        if (venueClassroom == null){
            throw new VenueRuntimeException(3005,"该教室不存在或状态异常");
        }
        return venueClassroom;
    }

    @Override
    public List<YVenueClassroom> loadClassroomByVenueId(Integer venueId) {
        return venueClassroomMapper.selectList(new QueryWrapper<YVenueClassroom>().eq("venue_id",venueId).eq("classroom_state",1));
    }

    /**
     * 新增教室信息
     * @param form
     * @return
     */
    @Override
    public Integer addClassroom(AddClassroomForm form) {
        RLock fairLock = redissonClient.getFairLock(RedisKey.addClassroomVenueIdLock(form.getVenueId()));
        RLock lock = redissonClient.getMultiLock(fairLock);
        Integer i = 0;
        try {
            // 尝试获取锁，最多等待20s
            boolean success = lock.tryLock(20, TimeUnit.SECONDS);
            if (success) {
                List<YVenueClassroom> classrooms = venueClassroomMapper.selectList(new QueryWrapper<YVenueClassroom>().eq("venue_id", form.getVenueId()).eq("classroom_id", form.getClassroomId()));
                if (classrooms.size()!=0){
                    throw new VenueRuntimeException(3011,"该场馆已经存在该教室");
                }

                YVenueClassroom classroom = BeanUtil.toBean(form, YVenueClassroom.class);
                classroom.setClassroomState(StateData.CLASSROOM_STATE_OK);
                 i = venueClassroomMapper.insert(classroom);


                QueryWrapper<YVenueBase> wrapper = new QueryWrapper<>();
                wrapper.eq("venue_id",form.getVenueId());
                YVenueBase venueBase = venueBaseMapper.selectOne(wrapper);
                if (venueBase.getClassroomNum()==null){ //这里要先判断null，不然新增教室永远是null，永远报错
                    venueBase.setClassroomNum(1);
                } else venueBase.setClassroomNum(venueBase.getClassroomNum()+1);
                venueBaseMapper.updateById(venueBase);
            } else {
                throw new Exception("服务器繁忙");
            }

        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            //释放锁
            lock.unlock();
        }
        return i;

    }

    /**
     * 教室弃用
     * @param id 教室id
     * @return
     */
    @Override
    public Integer dropClassroom(Integer id) {
        YVenueClassroom classroom = venueClassroomMapper.selectById(id);
        RLock fairLock = redissonClient.getFairLock(RedisKey.addClassroomVenueIdLock(classroom.getVenueId()));
        RLock lock = redissonClient.getMultiLock(fairLock);
        Integer i = 0;
        try {
            // 尝试获取锁，最多等待20s
            boolean success = lock.tryLock(20, TimeUnit.SECONDS);
            if (success) {
                if ( classroom.getClassroomState().equals(StateData.CLASSROOM_STATE_USELESS)){
                    throw new VenueRuntimeException(3012,"该教室状态异常");

                }
                classroom.setClassroomState(StateData.CLASSROOM_STATE_USELESS);
                i = venueClassroomMapper.updateById(classroom);

            } else {
                throw new Exception("服务器繁忙");
            }

        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            //释放锁
            lock.unlock();
        }
        return i;
    }


    /**
     * 分页查询所有类型
     * @param param
     * @return
     * @throws Exception
     */
    @Override
    public Page<YVenueClassroom> pageAllClassroom(PageAllClassroomParam param) throws YogaException {

        if (param.getPageNum() == null) {
            param.setPageNum(1);
        }
        if (param.getPageSize() == null) {
            param.setPageSize(5);
        }

        //拼接条件
        QueryWrapper<YVenueClassroom> wrapper = new QueryWrapper<YVenueClassroom>();
        wrapper.eq("venue_id",param.getVenueId());


        return baseMapper.selectPage(new Page<YVenueClassroom>(param.getPageNum(), param.getPageSize()), wrapper);
    }

    @Override
    public Integer enableClassroom(Integer id) throws YogaException {
        YVenueClassroom classroom = venueClassroomMapper.selectById(id);
        RLock fairLock = redissonClient.getFairLock(RedisKey.addClassroomVenueIdLock(classroom.getVenueId()));
        RLock lock = redissonClient.getMultiLock(fairLock);
        Integer i = 0;
        try {
            // 尝试获取锁，最多等待20s
            boolean success = lock.tryLock(20, TimeUnit.SECONDS);
            if (success) {
                if (Objects.equals(classroom.getClassroomState(), StateData.CLASSROOM_STATE_OK)){
                    throw new VenueRuntimeException(3012,"该教室状态异常");

                }
                classroom.setClassroomState(StateData.CLASSROOM_STATE_OK);
                i = venueClassroomMapper.updateById(classroom);

            } else {
                throw new Exception("服务器繁忙");
            }

        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            //释放锁
            lock.unlock();
        }
        return i;
    }
}
